package com.tank.server.handler;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.junit.runner.Request;

import com.tank.entity.Brick;
import com.tank.entity.Element;
import com.tank.entity.GameResource;
import com.tank.entity.Iron;
import com.tank.entity.Tank;
import com.tank.entity.Water;
import com.tank.request.CreateBulletRequest;
import com.tank.request.DestroyBrickRequest;
import com.tank.request.DestroyTankRequest;
import com.tank.request.PingRequest;
import com.tank.request.StartGameRequest;
import com.tank.request.TankLocationRequest;
import com.tank.response.CreateBulletResponse;
import com.tank.response.DestroyBrickResponse;
import com.tank.response.DestroyTankResponse;
import com.tank.response.InitialMapResponse;
import com.tank.response.PongResponse;
import com.tank.response.TankIdResponse;
import com.tank.response.TankLocationResponse;

import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.timeout.ReadTimeoutException;

public class TankServerHandler extends ChannelHandlerAdapter {

	@Override
	public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
		if (msg instanceof StartGameRequest) {
			// 创建地图
			InitialMapResponse response = createInitialMapResponse();
			Map<String, Tank> playerTanks = new HashMap<>();
			int x = 200;
			int y = 200;
			for (Channel channel : TankServer.Channel_Group) {
				String id = channel.id().asLongText();
				Tank tank = new Tank(x, y, Element.NORTH, id);
				playerTanks.put(id, tank);
				x += 200;
				y += 200;
			}
			response.setPlayerTanks(playerTanks);
			// 广播地图信息
			for (Channel channel : TankServer.Channel_Group) {
				channel.writeAndFlush(response);
			}
		} else if (msg instanceof TankLocationRequest) {
			TankLocationRequest request = (TankLocationRequest) msg;
			TankLocationResponse response = new TankLocationResponse(request);
			for (Channel channel : TankServer.Channel_Group) {
				if (!ctx.channel().id().equals(channel.id()))
					channel.writeAndFlush(response);
			}
		} else if (msg instanceof CreateBulletRequest) {
			CreateBulletRequest request = (CreateBulletRequest) msg;
			CreateBulletResponse response = new CreateBulletResponse(request);
			for (Channel channel : TankServer.Channel_Group) {
				if (!ctx.channel().id().equals(channel.id()))
					channel.writeAndFlush(response);
			}
		} else if (msg instanceof DestroyBrickRequest) {
			DestroyBrickRequest request = (DestroyBrickRequest) msg;
			DestroyBrickResponse response = new DestroyBrickResponse(request);
			for (Channel channel : TankServer.Channel_Group) {
				if (!ctx.channel().id().equals(channel.id()))
					channel.writeAndFlush(response);
			}
		} else if (msg instanceof DestroyTankRequest) {
			DestroyTankRequest request = (DestroyTankRequest) msg;
			DestroyTankResponse response = new DestroyTankResponse(request.getTankId());
			for (Channel channel : TankServer.Channel_Group) {
				if (!ctx.channel().id().equals(channel.id()))
					channel.writeAndFlush(response);
			}
		} else if (msg instanceof PingRequest) {
			ctx.writeAndFlush(new PongResponse());
		}
	}

	private InitialMapResponse createInitialMapResponse() {
		InitialMapResponse response = new InitialMapResponse();
		List<Brick> bricks = new ArrayList<>();
		List<Water> waters = new ArrayList<>();
		List<Iron> irons = new ArrayList<>();
		// 画出砖块
		for (int i = 0; i < 30; i++) {
			if (i % 2 == 0)
				continue;
			Brick brick = new Brick(20 * i + 10, 470);
			bricks.add(brick);
		}
		// 画出河流
		for (int i = 0; i < 25; i++) {
			Water water = new Water(20 * i + 60, 130);
			waters.add(water);
		}
		for (int i = 8; i < 15; i++) {
			Water water = new Water(100, 20 * i + 120);
			waters.add(water);
		}
		for (int i = 0; i < 25; i++) {
			if (i == 11 || i == 12 || i == 13)
				continue;
			Water water = new Water(20 * i + 60, 60);
			waters.add(water);
		}
		// 画出铁块
		for (int i = 0; i < 29; i++) {
			if (i % 2 == 0 || i % 3 == 0)
				continue;
			Iron iron = new Iron(20 * i + 10, 540);
			irons.add(iron);
		}
		Iron iron = new Iron(10, 540);
		irons.add(iron);
		for (int i = 0; i < 27; i++) {
			if (i % 3 == 0)
				continue;
			if (i >= 10 && i <= 15)
				continue;
			iron = new Iron(20 * i - 10, 200);
			irons.add(iron);
		}
		iron = new Iron(230, 150);
		irons.add(iron);
		iron = new Iron(230, 170);
		irons.add(iron);
		iron = new Iron(290, 200);
		irons.add(iron);

		iron = new Iron(290, 290);
		irons.add(iron);
		iron = new Iron(310, 290);
		irons.add(iron);
		iron = new Iron(290, 310);
		irons.add(iron);
		iron = new Iron(310, 310);
		irons.add(iron);
		iron = new Iron(590, 400);
		irons.add(iron);
		iron = new Iron(570, 400);
		irons.add(iron);

		Brick brick = new Brick(200, 290);
		bricks.add(brick);
		brick = new Brick(220, 290);
		bricks.add(brick);
		brick = new Brick(200, 310);
		bricks.add(brick);
		brick = new Brick(220, 310);
		bricks.add(brick);

		Water water = new Water(380, 290);
		waters.add(water);
		water = new Water(400, 290);
		waters.add(water);
		water = new Water(380, 310);
		waters.add(water);
		water = new Water(400, 310);
		waters.add(water);

		response.setBricks(bricks);
		response.setIrons(irons);
		response.setWaters(waters);
		return response;

	}

	@Override
	public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
		ctx.flush();
	}

	@Override
	public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
		if (cause instanceof ReadTimeoutException) {
			System.out.println("read time out");
		}
		cause.printStackTrace();
	}

	@Override
	public void channelActive(ChannelHandlerContext ctx) throws Exception {
		super.channelActive(ctx);
		// 将该channel保存起来
		TankServer.Channel_Group.add(ctx.channel());
		System.out.println("channel active,连接个数为" + TankServer.Channel_Group.size());
		// 发送tankId给客户端
		TankIdResponse response = new TankIdResponse();
		response.setTankId(ctx.channel().id().asLongText());
		ctx.writeAndFlush(response);
	}

	@Override
	public void channelInactive(ChannelHandlerContext ctx) throws Exception {
		super.channelInactive(ctx);
		System.out.println("channel inactive,连接个数为" + TankServer.Channel_Group.size());
	}

}
